package com.evan.review.handler;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;

import com.evan.review.R;

import java.lang.ref.WeakReference;

/**
 * Handler内存泄漏示例
 * <p>
 * 本Activity演示Handler常见的内存泄漏问题及解决方案，主要包括：
 * 1. 常见的Handler内存泄漏场景
 * 2. 泄漏问题出现的原因
 * 3. 使用静态内部类和弱引用解决
 * 4. 在Activity销毁时移除消息
 */
public class HandlerMemoryLeakActivity extends AppCompatActivity {

    private TextView tvExplanation;
    private Button btnLeakDemo;
    private Button btnFixedDemo1;
    private Button btnFixedDemo2;
    private Button btnOpenLeakActivity;

    // 问题1: 非静态内部类Handler会持有外部Activity引用
    // 当有延迟消息未处理，而Activity销毁时，会造成内存泄漏
    private final Handler leakyHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            // 一旦Activity被销毁，这里的代码可能会崩溃
            Toast.makeText(HandlerMemoryLeakActivity.this,
                    "收到消息: " + msg.what, Toast.LENGTH_SHORT).show();
        }
    };

    // 解决方案1: 使用静态内部类 + 弱引用
    private static class SafeHandler extends Handler {
        // 使用弱引用持有Activity
        private final WeakReference<HandlerMemoryLeakActivity> activityRef;

        SafeHandler(HandlerMemoryLeakActivity activity) {
            super(Looper.getMainLooper());
            this.activityRef = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            // 通过弱引用获取Activity实例
            HandlerMemoryLeakActivity activity = activityRef.get();
            // 先检查Activity是否还存在
            if (activity == null || activity.isFinishing()) {
                return; // Activity已经被销毁，安全退出
            }

            // 安全地处理消息
            Toast.makeText(activity,
                    "安全处理消息: " + msg.what, Toast.LENGTH_SHORT).show();
        }
    }

    // 使用安全的Handler实例
    private final SafeHandler safeHandler = new SafeHandler(this);

    // 解决方案2: 使用Handler.Callback
    private final Handler callbackHandler = new Handler(Looper.getMainLooper(), msg -> {
        // 如果Activity已经销毁，不做任何处理
        if (isFinishing()) return true;

        // 安全处理
        Toast.makeText(HandlerMemoryLeakActivity.this,
                "Callback处理消息: " + msg.what, Toast.LENGTH_SHORT).show();
        return true;
    });

    /**
     * 演示Activity被回收后Handler的安全处理
     */
    private static class SafeMessageHandler extends Handler {
        private final WeakReference<HandlerMemoryLeakActivity> activityRef;
        private final String handlerName; // 用于标识不同的Handler实例

        SafeMessageHandler(HandlerMemoryLeakActivity activity, String name) {
            super(Looper.getMainLooper());
            this.activityRef = new WeakReference<>(activity);
            this.handlerName = name;
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            HandlerMemoryLeakActivity activity = activityRef.get();
            
            // 情况1: Activity已被回收
            if (activity == null) {
                Log.d("HandlerDemo", handlerName + ": Activity已被回收，但Handler仍在处理消息");
                // 可以在这里处理一些不依赖Activity的逻辑
                // 比如保存数据到数据库、发送网络请求等
                return;
            }
            
            // 情况2: Activity存在但已结束
            if (activity.isFinishing()) {
                Log.d("HandlerDemo", handlerName + ": Activity已结束，但Handler仍在处理消息");
                return;
            }
            
            // 情况3: Activity正常存在
            Log.d("HandlerDemo", handlerName + ": Activity正常，处理消息: " + msg.what);
            // 安全地使用Activity
            activity.tvExplanation.setText(handlerName + "处理消息: " + msg.what);
        }
    }

    // 创建两个Handler实例来演示不同情况
    private final SafeMessageHandler handler1 = new SafeMessageHandler(this, "Handler1");
    private final SafeMessageHandler handler2 = new SafeMessageHandler(this, "Handler2");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_handler_memory_leak);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        initViews();
        setupListeners();

        // 显示内存泄漏解释
        showMemoryLeakExplanation();
    }

    private void initViews() {
        tvExplanation = findViewById(R.id.tv_explanation);
        btnLeakDemo = findViewById(R.id.btn_leak_demo);
        btnFixedDemo1 = findViewById(R.id.btn_fixed_demo1);
        btnFixedDemo2 = findViewById(R.id.btn_fixed_demo2);
        btnOpenLeakActivity = findViewById(R.id.btn_open_leak_activity);
    }

    private void setupListeners() {
        // 泄漏版本：使用非静态内部类Handler发送延迟消息
        btnLeakDemo.setOnClickListener(v -> {
            tvExplanation.setText("已发送10秒延迟消息到leakyHandler。\n\n" +
                    "如果在消息处理前退出Activity，将导致内存泄漏，" +
                    "因为Handler是非静态内部类，持有外部Activity的引用。");

            // 发送10秒延迟消息
            leakyHandler.sendEmptyMessageDelayed(1, 10000);
            Toast.makeText(this, "已发送10秒延迟消息", Toast.LENGTH_SHORT).show();
        });

        // 修复版本1：使用静态内部类 + 弱引用
        btnFixedDemo1.setOnClickListener(v -> {
            tvExplanation.setText("已发送10秒延迟消息到safeHandler(静态内部类+弱引用)。\n\n" +
                    "即使在消息处理前退出Activity，也不会导致内存泄漏，" +
                    "因为Handler是静态内部类，只通过弱引用持有Activity。");

            // 发送10秒延迟消息
            safeHandler.sendEmptyMessageDelayed(2, 10000);
            Toast.makeText(this, "已发送10秒延迟消息", Toast.LENGTH_SHORT).show();
        });

        // 修复版本2：在onDestroy中移除所有消息
        btnFixedDemo2.setOnClickListener(v -> {
            tvExplanation.setText("已发送10秒延迟消息到callbackHandler。\n\n" +
                    "即使Handler是内部类，在onDestroy中调用removeCallbacksAndMessages(null)" +
                    "可以移除所有消息，避免内存泄漏。");

            // 发送10秒延迟消息
            callbackHandler.sendEmptyMessageDelayed(3, 10000);
            Toast.makeText(this, "已发送10秒延迟消息", Toast.LENGTH_SHORT).show();
        });

        // 打开一个新的LeakActivity演示完整生命周期
        btnOpenLeakActivity.setOnClickListener(v -> {
            Toast.makeText(this, "应打开一个新的Activity，但此示例仅做演示",
                    Toast.LENGTH_SHORT).show();
        });
    }

    private void showMemoryLeakExplanation() {
        String explanation = "Handler内存泄漏问题解析：\n\n" +
                "1. 问题根源：\n" +
                "   非静态内部类Handler持有外部Activity的引用，" +
                "当有延迟消息未处理而Activity销毁时，" +
                "由于消息队列引用了Handler，Handler又引用了Activity，" +
                "导致Activity无法被回收。\n\n" +
                "2. 解决方案：\n" +
                "   a) 使用静态内部类 + 弱引用\n" +
                "   b) 在Activity销毁时移除所有回调和消息\n" +
                "   c) 使用LifecycleOwner自动管理Handler生命周期";

        tvExplanation.setText(explanation);
    }

    /**
     * 演示在Activity销毁时清理所有Handler消息，防止内存泄漏
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();

        // 解决方案：在Activity销毁时移除所有消息和回调
        leakyHandler.removeCallbacksAndMessages(null);
        safeHandler.removeCallbacksAndMessages(null);
        callbackHandler.removeCallbacksAndMessages(null);

        // 注意：即使调用了removeCallbacksAndMessages方法，
        // 对于非静态内部类Handler，如果使用引用被其他长生命周期对象持有，
        // 仍然可能发生内存泄漏，所以最安全的做法是同时使用静态内部类+弱引用
    }

    /**
     * 这是一个更完整的示例：使用Lifecycle组件自动管理Handler生命周期
     * 需要添加lifecycle-runtime依赖
     */

    // 结合Lifecycle使用的Handler示例
    public class LifecycleAwareHandler implements LifecycleObserver {
        private final Handler handler = new Handler(Looper.getMainLooper());

        public LifecycleAwareHandler(LifecycleOwner lifecycleOwner) {
            // 添加到生命周期观察者
            lifecycleOwner.getLifecycle().addObserver(this);
        }

        public void postDelayed(Runnable r, long delayMillis) {
            handler.postDelayed(r, delayMillis);
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        private void onDestroy() {
            // 自动在Lifecycle销毁时清理
            handler.removeCallbacksAndMessages(null);
        }
    }


    /**
     * 内部类示例
     * 展示静态内部类、非静态内部类和匿名内部类的区别
     */
    // 1. 静态内部类
    private static class StaticInnerClass {
        // 静态内部类不能直接访问外部类的非静态成员
        // 需要通过外部类实例来访问
        private final HandlerMemoryLeakActivity outerActivity;

        StaticInnerClass(HandlerMemoryLeakActivity activity) {
            this.outerActivity = activity;
        }

        void doSomething() {
            // 需要通过outerActivity来访问外部类的非静态成员
            outerActivity.tvExplanation.setText("这是静态内部类");
        }
    }

    // 2. 非静态内部类
    private class NonStaticInnerClass {
        // 非静态内部类可以直接访问外部类的所有成员
        void doSomething() {
            // 直接访问外部类的成员
            tvExplanation.setText("这是非静态内部类");
        }
    }

    // 3. 匿名内部类示例
    private void showAnonymousInnerClassExample() {
        // 匿名内部类示例1：实现接口
        View.OnClickListener clickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tvExplanation.setText("这是匿名内部类实现的OnClickListener");
            }
        };

        // 匿名内部类示例2：继承类
        Handler anonymousHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                tvExplanation.setText("这是匿名内部类继承的Handler");
            }
        };
    }

    /**
     * 内部类内存泄漏示例
     */
    private void demonstrateInnerClassMemoryLeak() {
        // 1. 静态内部类 - 安全
        StaticInnerClass staticInner = new StaticInnerClass(this);

        // 2. 非静态内部类 - 可能导致内存泄漏
        NonStaticInnerClass nonStaticInner = new NonStaticInnerClass();

        // 3. 匿名内部类 - 可能导致内存泄漏
        Handler leakyAnonymousHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                // 持有外部Activity的引用
                tvExplanation.setText("这是可能导致内存泄漏的匿名内部类Handler");
            }
        };

        // 4. 安全的匿名内部类 - 使用静态内部类+弱引用
        Handler safeAnonymousHandler = new Handler(Looper.getMainLooper()) {
            private final WeakReference<HandlerMemoryLeakActivity> activityRef =
                    new WeakReference<>(HandlerMemoryLeakActivity.this);

            @Override
            public void handleMessage(@NonNull Message msg) {
                HandlerMemoryLeakActivity activity = activityRef.get();
                if (activity != null && !activity.isFinishing()) {
                    activity.tvExplanation.setText("这是安全的匿名内部类Handler");
                }
            }
        };
    }

    private void demonstrateHandlerAfterActivityRecycled() {
        // 发送延迟消息
        handler1.sendEmptyMessageDelayed(1, 5000);  // 5秒后处理
        handler2.sendEmptyMessageDelayed(2, 15000); // 15秒后处理
        
        // 说明：如果用户在5秒内退出Activity
        // handler1的消息会在Activity被回收后处理
        // handler2的消息会在Activity被回收后处理
        // 两个Handler都会安全地处理消息，不会崩溃
    }
} 